`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: CBICR, Tsinghua Univ.
// Engineer: Hongyi Li
// 
// Create Date: 2024/12/24 13:31:12
// Design Name: 
// Module Name: Allocator
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//////////////////////////////////////////////////////////////////////////////////


module SeparableAllocator
#(
    parameter N = 'd4,  // Requests
    parameter M = 'd3   // Resource
)(
    input          clk, rst_n,
    input  [N*M-1:0] i_nm_req,
    output [M*N-1:0] o_mn_grant
);

wire [N*M-1:0] nm_o_wire;
wire [N*M-1:0] mn_i_wire;

genvar i, j;
generate
    for (i = 0; i < M; i = i + 1) begin
        RoundRobinArbitor #(.N(N)) ArbN (
            .clk(clk), .rst_n(rst_n),
            .i_req(i_nm_req[((i + 1) * N) - 1 : (i * N)]), 
            .o_grant(nm_o_wire[((i + 1) * N) - 1 : (i * N)])
        );
    end
    for (j = 0; j < N; j = j + 1) begin
        RoundRobinArbitor #(.N(M)) ArbM (
            .clk(clk), .rst_n(rst_n),
            .i_req(mn_i_wire[((j + 1) * M) - 1 : (j * M)]), 
            .o_grant(o_mn_grant[((j + 1) * M) - 1 : (j * M)])
        );
    end
    for (j = 0; j < N; j = j + 1) begin
        for (i = 0; i < M; i = i + 1) begin
            assign mn_i_wire[j * M + i] = nm_o_wire[i * N + j];
        end
    end
endgenerate
endmodule